<template>
	<div class="layout-ui" :style="styleParams">
		<layout-header :top-menu-flag="topMenuFlag" @click="changeTopMenu" @logout="userLogout"></layout-header>

		<layout-side-menu
			v-if="cSideMenuShow"
			style="flex-shrink: 0"
			:collapsed="collapsed"
			:actives="sideMenuKeys"
			:top-key="topMenuFlag"
			@click="changeSideMenu"
			@collapsed="collapsedSideMenu"
		></layout-side-menu>

		<div class="layout-page-region">
			<router-view style="min-width: 1400px"></router-view>
		</div>

		<teleport v-if="routeloading" to="body">
			<div class="shade-page" style="background-color: rgba(0, 0, 0, 0.85)">
				<a-spin size="large" tip="加载中..."></a-spin>
			</div>
		</teleport>
	</div>
</template>

<script setup lang="ts" name="Layout">
import { g6Debounce, g6StorageValue } from 'glasssix-utils-ts';
import { LayoutHeader, LayoutSideMenu } from './_components';

// 监听路由
const route = useRoute();
const router = useRouter();
// 布局尺寸
const styleParams = reactive({
	'--layout-header': '76px',
	'--side-width': '186px'
});

// 页面切换loading
const routeloading = ref(false);

// 整体菜单
const sysMenus = ref<TsGlobalType.TsRoleMenu[]>([]);

// 左侧菜单收缩状态
const collapsed = ref(false);

// 当前选中的左侧菜单
const sideMenuKeys = ref<string[]>([]);

// 是否加载左侧菜单
const showSideMenu = ref(false);

// 当前选中的顶部菜单标识
const topMenuFlag = ref('');

// 切换左侧菜单显示隐藏
const collapsedSideMenu = g6Debounce((flag: boolean) => {
	collapsed.value = flag;
}, 150);

// 左侧菜单切换
const changeSideMenu = (keyPath: string) => {
	sideMenuKeys.value = [keyPath];
	router.push(keyPath);
	g6StorageValue.save('session', 'sideMenuKey', keyPath);
};

// 顶部菜单切换
const changeTopMenu = (item: TsGlobalType.TsRoleMenu) => {
	routeloading.value = true;
	topMenuFlag.value = item.code;
	let timer = setTimeout((): any => {
		g6StorageValue.save('session', 'topMenuKey', item.code);
		if (item.ext.menuType === 'default-page') {
			collapsed.value = false;
			showSideMenu.value = false;
			sideMenuKeys.value = [];
			router.push(item.path);
		}
		if (item.ext.menuType === 'directory') {
			showSideMenu.value = true;
			const firstSub = item.childList[0];
			changeSideMenu(firstSub.path);
		}

		routeloading.value = false;
		clearTimeout(timer);
	}, 200);
};

// 从 sessionStorage 中 获取菜单数据
const getSystemMenus = () => {
	if (Array.isArray(g6StorageValue.get('session', 'sysMenus'))) {
		sysMenus.value = g6StorageValue.get('session', 'sysMenus') as TsGlobalType.TsRoleMenu[];
		// 如果第一次加载的时候没有选中的顶部和侧边菜单标识
		const firstTop = sysMenus.value[0];
		if (!topMenuFlag.value) {
			topMenuFlag.value = firstTop.code;
		}
		if (sideMenuKeys.value.length === 0) {
			if (firstTop.ext.menuType === 'directory') {
				const subList = firstTop.childList;
				const firstSub = subList[0];
				sideMenuKeys.value = [firstSub.path];
				showSideMenu.value = true;
			}
		}
	}
};

// 刷新后从 sessionStorage 中获取选中的顶部和侧边菜单
const getSelectedMenuKey = () => {
	const topMenuKey = g6StorageValue.get('session', 'topMenuKey') as string;
	const sideMenuKey = g6StorageValue.get('session', 'sideMenuKey') as string;
	topMenuFlag.value = topMenuKey ? topMenuKey : '';
	sideMenuKeys.value = sideMenuKey ? [sideMenuKey] : [];
	if (Array.isArray(g6StorageValue.get('session', 'flatMenus'))) {
		const flatMenus = g6StorageValue.get('session', 'flatMenus') as TsGlobalType.TsRoleMenu[];
		if (!flatMenus) {
			return;
		}
		const topItem = flatMenus.find((item: TsGlobalType.TsRoleMenu) => item.code === topMenuFlag.value);
		showSideMenu.value = topItem?.ext.menuType === 'directory';
	}
};

// 注销
const userLogout = () => {
	// 清除sessionStorage, 然后进入登录页
	window.sessionStorage.clear();
	router.replace({ path: '/login' });
};
const cSideMenuShow = computed(() => {
	return showSideMenu.value && !route.meta.LayoutNoSideMenu;
});
const watchCollapsed = computed(() => collapsed.value);
const watchEffectStop = watchEffect(() => {
	styleParams['--side-width'] = !watchCollapsed.value ? '184px' : '64px';
});

onMounted(() => {
	getSelectedMenuKey();
	getSystemMenus();
	topMenuFlag.value = route.matched[1].name as string;
});
onUnmounted(() => {
	watchEffectStop();
});
</script>

<style lang="less" scoped>
.layout-ui {
	display: flex;
	overflow-y: hidden;
	width: 100vw;
	height: 100vh;
	padding-top: var(--layout-header);
	background-image: url('@/global-assets/imgs/global-background.png');
	background-repeat: no-repeat;
	background-position: center;
	background-size: 101% 100%;

	.layout-page-region {
		flex: 1;
		overflow-x: auto;
		height: calc(100vh - var(--layout-header));
	}
}
</style>
